/**
 * @file   log.h
 * @brief  log打印输出类
 * @encode UTF-8
 * @log    date        author      notes
 *         2021.09.17  Jimmy       first version
 */
#ifndef __LOG_H_ 
#define __LOG_H_ 
#include <iostream>
#include <string>
#include <mutex>

/* 控制台输出颜色 */
/* 前景色 Front Color */
#define FC_BLACK        "\033[30m"      /* 黑色 */
#define FC_RED          "\033[31m"      /* 红色 */
#define FC_GREEN        "\033[32m"      /* 绿色 */
#define FC_YELLOW       "\033[33m"      /* 黄色 */
#define FC_BLUE         "\033[34m"      /* 蓝色 */
#define FC_PURPLE       "\033[35m"      /* 紫色 */
#define FC_CYAN         "\033[36m"      /* 青色 */
#define FC_WHITE        "\033[37m"      /* 白色 */

/* 背景色 Background Color */
#define BC_BLACK        "\033[40m"      /* 黑色 */
#define BC_RED          "\033[41m"      /* 红色 */
#define BC_GREEN        "\033[42m"      /* 绿色 */
#define BC_YELLOW       "\033[43m"      /* 黄色 */
#define BC_BLUE         "\033[44m"      /* 蓝色 */
#define BC_PURPLE       "\033[45m"      /* 紫色 */
#define BC_CYAN         "\033[46m"      /* 青色 */
#define BC_WHITE        "\033[47m"      /* 白色 */

#define COLOR_CLR       "\033[0m"       /* 清除颜色设置 */

namespace log_shell
{
enum LogLevel
{
    LOG_LEVEL_FATAL = 0,        /* 致命错误 */
    LOG_LEVEL_ERROR,            /* 错误 */
    LOG_LEVEL_WARN,             /* 警告 */
    LOG_LEVEL_INFO,             /* 普通日志输出 */
    LOG_LEVEL_DEBUG,            /* 调试 */
};

struct LogConfig
{
    bool     logPrintf;                             /* 打印到控制台 */
    LogLevel logLevel = log_shell::LOG_LEVEL_INFO;  /* 日志级别 */
};

class DebugLog
{
    public:
        static int init(const LogConfig & logConfig);

        static int init(const bool & logPrintf = true, const LogLevel & logLevel = LOG_LEVEL_INFO);

        static void log(
            const std::string & file,
            const std::string & func,
            const uint32_t    & line,
            const LogLevel    & logLevel,
            const char        * fmt, ...
            );

    private:
        static LogConfig        mLogConfig;
        static std::mutex       mOutMutex;
        static std::string      getBaseName(const std::string & pathName);
        static std::string      getHumanityTimeStr(const uint64_t & us);
};

#define LOG_FATAL(...)      DebugLog::log(__FILE__, __func__, __LINE__, log_shell::LOG_LEVEL_FATAL, __VA_ARGS__)
#define LOG_ERROR(...)      DebugLog::log(__FILE__, __func__, __LINE__, log_shell::LOG_LEVEL_ERROR, __VA_ARGS__)
#define LOG_WARN(...)       DebugLog::log(__FILE__, __func__, __LINE__, log_shell::LOG_LEVEL_WARN, __VA_ARGS__)
#define LOG_INFO(...)       DebugLog::log(__FILE__, __func__, __LINE__, log_shell::LOG_LEVEL_INFO, __VA_ARGS__)
#define LOG_DEBUG(...)      DebugLog::log(__FILE__, __func__, __LINE__, log_shell::LOG_LEVEL_DEBUG, __VA_ARGS__)


}

#endif	/* __LOG_H_ */

/* End of file */
